package com.music.profile.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.music.profile.PMF;
import com.music.profile.beans.Member;
import com.music.profile.beans.Playlist;
import com.music.profile.beans.Song;
import com.music.profile.constants.PlaylistState;

public class PlaylistDAOImpl implements PlaylistDAO {

	/* (non-Javadoc)
	 * @see com.music.profile.dao.impl.PlaylistDAO#createPlaylist(java.lang.String, java.lang.Long)
	 */
	public Long createPlaylist(String playlistName, Long memberId) {
		Playlist playlist = new Playlist(null, playlistName, KeyFactory.createKey(Member.class.getSimpleName(), memberId),
				PlaylistState.ACTIVE, 0L, new Date(), new Date(), null);
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();
		try {
			playlist = persistenceManager.makePersistent(playlist);
		} finally {
			persistenceManager.close();
		}
		return playlist.getPlaylistId();
	}

	/* (non-Javadoc)
	 * @see com.music.profile.dao.impl.PlaylistDAO#updatePlaylist(com.music.profile.beans.Playlist)
	 */
	public boolean updatePlaylist(Playlist playlist) {
		// Set the last update date to current date.
		playlist.setLastUpdateDate(new Date());
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();
		try {
			playlist = persistenceManager.makePersistent(playlist);
		} finally {
			persistenceManager.close();
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see com.music.profile.dao.impl.PlaylistDAO#getPlaylist(java.lang.Long)
	 */
	public Playlist getPlaylist(Long playlistId) {
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();

		return getPlaylist(playlistId, persistenceManager);

	}
	/**
	 * This method is created to handle transactionally getting the playlist item.
	 * The transaction is maintained by the persistence manager. So, we are having it in one of the arguments.
	 * @param playlistId
	 * @param persistenceManager
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Playlist getPlaylist(Long playlistId,
			PersistenceManager persistenceManager) {
		Query query = persistenceManager.newQuery(Playlist.class);
		query.setFilter("playlistId == playlistIdParam");
		query.declareParameters("String playlistParam");
		List<Playlist> results;
		results = (List<Playlist>) query.execute(playlistId);

		if (results == null || results.isEmpty()) {
			return null;
		}
		return results.get(0);
	}
	/* (non-Javadoc)
	 * @see com.music.profile.dao.impl.PlaylistDAO#deletePlaylist(java.lang.Long)
	 */
	public boolean deletePlaylist(Long playlistId) {
		PersistenceManager persistenceManager = PMF.get().getPersistenceManager();
		Transaction tx = persistenceManager.currentTransaction();

		try {
			tx.begin(); // Begin the transaction
			Playlist playlist = getPlaylist(playlistId, persistenceManager); // check its existence
			if (playlist == null) {
				// No play list exists with the given id.
				return false;
			}
			persistenceManager.deletePersistent(playlist); // Delete if exists.
			tx.commit();
		} finally {
			if(tx.isActive()) {
				tx.rollback();
			}
			persistenceManager.close();
		}

		return true;
	}

	/* (non-Javadoc)
	 * @see com.music.profile.dao.impl.PlaylistDAO#addSongsToPlaylist(java.lang.Long, java.util.List)
	 */
	public boolean addSongsToPlaylist(Long playlistId, List<Long> songsList) {
		List<Key> allKeys = null;
		PersistenceManager persistenceManager = PMF.get().getPersistenceManager();
		Transaction tx = persistenceManager.currentTransaction();

		try {
			tx.begin(); // Begin the transaction
			Playlist playlist = getPlaylist(playlistId, persistenceManager); // check its existence
			if (playlist == null) {
				// No play list exists with the given id.
				return false;
			}
			allKeys = playlist.getSongsList();
			if(allKeys == null) { // Adding songs the first time. 
				allKeys = new ArrayList<Key>(songsList.size());
			}
			for (Long long1 : songsList) {
				Key k = KeyFactory.createKey(Song.class.getSimpleName(), long1);
				allKeys.add(k);
			}
			persistenceManager.makePersistent(playlist);
			tx.commit();
		} finally {
			if(tx.isActive()) {
				tx.rollback();
			}
			persistenceManager.close();
		}
		return true;
	}
}
